﻿using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;

namespace WindsorInitConfig {
    /// <summary>
    ///   http://stackoverflow.com/questions/3986747/how-to-reuse-a-transient-dependency-in-same-context-with-castle-windsor-di-contai
    /// </summary>
    [TestFixture]
    public class DatabaseRepositoryContext {
        public class Database {}

        public interface IRepository {
            Database Database { get; }
        }

        public interface IFooRepository : IRepository {}

        public interface IBarRepository : IRepository {}

        public class FooRepository : IFooRepository {
            public Database Database { get; private set; }

            public FooRepository(Database database) {
                Database = database;
            }
        }

        public class BarRepository : IBarRepository {
            public Database Database { get; private set; }

            public BarRepository(Database database) {
                Database = database;
            }
        }

        public class Consumer {
            public IFooRepository fooRepository { get; private set; }
            public IBarRepository barRepository { get; private set; }

            public Consumer(IFooRepository fooRepository, IBarRepository barRepository) {
                this.fooRepository = fooRepository;
                this.barRepository = barRepository;
            }
        }

        private IWindsorContainer container;

        [Test]
        public void SameDatabaseIsUsed() {
            var consumer = container.Resolve<Consumer>();
            var fooRepository = consumer.fooRepository;
            var barRepository = consumer.barRepository;
            Assert.AreEqual(fooRepository.Database, barRepository.Database); //FAILS
        }

        [Test]
        public void DifferentDatabaseIsUsed() {
            var consumer = container.Resolve<Consumer>();
            var fooRepository = consumer.fooRepository;
            var consumer2 = container.Resolve<Consumer>();
            var barRepository = consumer2.barRepository;
            Assert.AreNotEqual(fooRepository.Database, barRepository.Database); //PASSES
        }

        [SetUp]
        public void SetUp() {
            container = new WindsorContainer();
            container.Register(
                Component.For<Database>().ImplementedBy<Database>().LifeStyle.Transient,
                Component.For<IFooRepository>().ImplementedBy<FooRepository>().LifeStyle.Transient,
                Component.For<IBarRepository>().ImplementedBy<BarRepository>().LifeStyle.Transient,
                Component.For<Consumer>().ImplementedBy<Consumer>().LifeStyle.Transient
                );
        }
    }
}